home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / shutdown.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-29  |  5.5 KB  |  237 lines

  1. /*
  2.  *  Window Maker window manager
  3.  * 
  4.  *  Copyright (c) 1997, 1998 Alfredo K. Kojima
  5.  * 
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  19.  *  USA.
  20.  */
  21.  
  22. #include "wconfig.h"
  23.  
  24. #include <stdlib.h>
  25. #include <signal.h>
  26. #include <unistd.h>
  27.  
  28. #include <X11/Xlib.h>
  29. #include <X11/Xutil.h>
  30. #include <X11/Intrinsic.h>
  31.  
  32. #include "WindowMaker.h"
  33. #include "window.h"
  34. #include "client.h"
  35. #include "funcs.h"
  36. #include "properties.h"
  37. #include "session.h"
  38. #include "winspector.h"
  39. #ifdef KWM_HINTS
  40. # include "kwm.h"
  41. #endif
  42. #ifdef OLWM_HINTS
  43. # include "openlook.h"
  44. #endif
  45.  
  46. extern Atom _XA_WM_DELETE_WINDOW;
  47. extern Time LastTimestamp;
  48. extern int wScreenCount;
  49.  
  50.  
  51. static void wipeDesktop(WScreen *scr);
  52.  
  53.  
  54. /*
  55.  *----------------------------------------------------------------------
  56.  * Shutdown-
  57.  *     Exits the window manager cleanly. If mode is WSLogoutMode,
  58.  * the whole X session will be closed, by killing all clients if
  59.  * no session manager is running or by asking a shutdown to
  60.  * it if its present.
  61.  * 
  62.  *----------------------------------------------------------------------
  63.  */
  64. void
  65. Shutdown(WShutdownMode mode)
  66. {
  67.     int i;
  68.  
  69.     switch (mode) {
  70.      case WSLogoutMode:
  71. #ifdef XSMP_ENABLED
  72.     wSessionRequestShutdown();
  73.     break;
  74. #else
  75.     /* fall through */
  76. #endif
  77.      case WSKillMode:
  78.      case WSExitMode:
  79.     /* if there is no session manager, send SAVE_YOURSELF to
  80.      * the clients */
  81. #if 0
  82. #ifdef XSMP_ENABLED
  83.     if (!wSessionIsManaged())
  84. #endif
  85.         for (i = 0; i < wScreenCount; i++) {
  86.         WScreen *scr;
  87.  
  88.         scr = wScreenWithNumber(i);
  89.         if (scr) {
  90.             wSessionSendSaveYourself(scr);
  91.         }
  92.         }
  93. #endif
  94.     for (i = 0; i < wScreenCount; i++) {
  95.         WScreen *scr;
  96.  
  97.         scr = wScreenWithNumber(i);
  98.         if (scr) {
  99.         if (scr->helper_pid)
  100.             kill(scr->helper_pid, SIGKILL);
  101.  
  102.         /* if the session is not being managed, save restart info */
  103. #ifdef XSMP_ENABLED
  104.         if (!wSessionIsManaged())
  105. #endif
  106.             wSessionSaveClients(scr);
  107.  
  108. #ifdef KWM_HINTS
  109.         wKWMShutdown(scr, True);
  110. #endif
  111.         wScreenSaveState(scr);
  112.  
  113.         if (mode == WSKillMode)
  114.             wipeDesktop(scr);
  115.         else
  116.             RestoreDesktop(scr);
  117.         }
  118.     }
  119.     ExecExitScript();
  120.     Exit(0);
  121.     break;
  122.  
  123.      case WSRestartPreparationMode:
  124.     for (i=0; i<wScreenCount; i++) {
  125.         WScreen *scr;
  126.  
  127.         scr = wScreenWithNumber(i);
  128.         if (scr) {
  129.         if (scr->helper_pid)
  130.             kill(scr->helper_pid, SIGKILL);
  131. #ifdef KWM_HINTS
  132.         wKWMShutdown(scr, False);
  133. #endif
  134. #ifdef OLWM_HINTS
  135.         wOLWMShutdown(scr);
  136. #endif
  137.         wScreenSaveState(scr);
  138.  
  139.         RestoreDesktop(scr);
  140.         }
  141.     }
  142.     break;
  143.     }
  144. }
  145.  
  146.  
  147.  
  148.  
  149. /*
  150.  *----------------------------------------------------------------------
  151.  * RestoreDesktop--
  152.  *     Puts the desktop in a usable state when exiting.
  153.  *
  154.  * Side effects:
  155.  *     All frame windows are removed and windows are reparented
  156.  * back to root. Windows that are outside the screen are 
  157.  * brought to a viable place. 
  158.  * 
  159.  *---------------------------------------------------------------------- 
  160.  */
  161. void
  162. RestoreDesktop(WScreen *scr)
  163. {
  164.     WMBagIterator iter;
  165.     WCoreWindow *core;
  166.  
  167.     if (scr->helper_pid > 0) {
  168.     kill(scr->helper_pid, SIGTERM);
  169.     scr->helper_pid = 0;
  170.     }
  171.  
  172.     XGrabServer(dpy);
  173.     wDestroyInspectorPanels();
  174.  
  175.     /* reparent windows back to the root window, keeping the stacking order */
  176.     for (core = WMBagFirst(scr->stacking_list, &iter);
  177.      iter != NULL;
  178.      core = WMBagNext(scr->stacking_list, &iter)) {
  179.         WCoreWindow *next;
  180.         WWindow *wwin;
  181.  
  182.         /* go to the end of the list */
  183.         while (core->stacking->under)
  184.             core = core->stacking->under;
  185.         
  186.         while (core) {
  187.             next = core->stacking->above;
  188.             
  189.             if (core->descriptor.parent_type==WCLASS_WINDOW) {
  190.         Window window;
  191.  
  192.                 wwin = core->descriptor.parent;
  193.         window = wwin->client_win;
  194.                 wUnmanageWindow(wwin, !wwin->flags.internal_window, False);
  195.         XMapWindow(dpy, window);
  196.             }
  197.             core = next;
  198.         }
  199.     }
  200.  
  201.     XUngrabServer(dpy);
  202.     XSetInputFocus(dpy, PointerRoot, RevertToParent, CurrentTime);
  203.     wColormapInstallForWindow(scr, NULL);
  204.     PropCleanUp(scr->root_win);
  205.     XSync(dpy, 0);
  206. }
  207.  
  208.  
  209. /*
  210.  *----------------------------------------------------------------------
  211.  * wipeDesktop--
  212.  *     Kills all windows in a screen. Send DeleteWindow to all windows
  213.  * that support it and KillClient on all windows that don't.
  214.  * 
  215.  * Side effects:
  216.  *     All managed windows are closed.
  217.  * 
  218.  * TODO: change to XQueryTree()
  219.  *---------------------------------------------------------------------- 
  220.  */
  221. static void
  222. wipeDesktop(WScreen *scr)
  223. {
  224.     WWindow *wwin;
  225.  
  226.     wwin = scr->focused_window;
  227.     while (wwin) {
  228.     if (wwin->protocols.DELETE_WINDOW)
  229.         wClientSendProtocol(wwin, _XA_WM_DELETE_WINDOW, LastTimestamp);
  230.     else
  231.         wClientKill(wwin);
  232.     wwin = wwin->prev;
  233.     }
  234.     XSync(dpy, False);
  235. }
  236.  
  237.